package com.dxy.app.widget.shrink_upvote;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Typeface;
import android.support.annotation.Nullable;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.view.View;
import com.dxy.app.R;
import com.dxy.app.widget.ThreadManager;

/**
 * Created by duxingyu on 2017/7/19.16:08
 * Email:
 * Description:仿饿了么评论表情
 **/
public abstract class ShrinkUpvoteView extends View implements View.OnClickListener {

  public static final String TAG = "TAG_UpvoteView";
  /**
   * 动作增量
   */
  public static final int INCRES_DELY = 3;
  /**
   * 更新消息的时间间隔
   */
  public static final int SHRINK_TIME = 20;
  /**
   * 提示文字的字体大小
   */
  private int textSize;
  /**
   * 画笔
   */
  protected Paint paint;
  /**
   * 绘制文字的画笔
   */
  private TextPaint textPaint;
  /**
   * 当前表情是否被选中,默认都是未被选中的
   */
  protected boolean selectState = false;
  /**
   * 当前表情是否是默认选中的表情
   */
  protected boolean defaultState = false;
  /**
   * 绘制文字的起始X轴坐标，Y轴坐标
   */
  private float startPromX, startPromY;
  /**
   * 当前表情所属类型
   */
  protected VoteType type;
  /**
   * Y轴方向上的偏移量,默认是0
   */
  private float curOffsetY = 0;
  /**
   * 提示信息
   * */
  private String promptStr;
  /**
   * 表情类型
   */
  public enum VoteType {
    DISLIKE, JUST, LIKE
  }
  /**
   * 所需的颜色资源
   */
  protected int colorBorder,//当前边框颜色
      colorFill,//当前填充颜色
      colorBorderUnsel,//未选中时的边框颜色
      colorBorderSel,//未选中时的填充色
      colorFillUnsel,//选中时的边框颜色
      colorFillSel;//选中时的填充色
  /**
   * 表情的一些尺寸
   */
  protected float width,//表情宽度
      height,//表情高度
      borderWidth = 5;//表情边框

  /**
   * 一些变量
   */
  protected float positionX,//表情的x轴
      positionY,//y轴基准值
      radius,//表情的半径
      eyeRadius,//眼睛半径
      eyeToMiddleX,//眼睛距离中线距离
      eyeToTopY;//眼睛距离水平线距离

  public ShrinkUpvoteView(Context context) {
    super(context);
    init(null);
  }

  public ShrinkUpvoteView(Context context, @Nullable AttributeSet attrs) {
    super(context, attrs);
    TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.ShrinkUpvoteView);
    init(array);
  }

  public ShrinkUpvoteView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.ShrinkUpvoteView);
    init(array);
  }

  /**
   * 初始化表情所需的参数
   */
  private void init(TypedArray array) {
    setOnClickListener(this);
    if (array != null) {
      colorBorderSel = array.getColor(R.styleable.ShrinkUpvoteView_shrink_border, Color.BLUE);
      colorFillSel = array.getColor(R.styleable.ShrinkUpvoteView_shrink_fill, Color.GREEN);
      width = array.getDimensionPixelSize(R.styleable.ShrinkUpvoteView_shrink_width, 25);
      height = array.getDimensionPixelSize(R.styleable.ShrinkUpvoteView_shrink_height, 100);
      defaultState = array.getBoolean(R.styleable.ShrinkUpvoteView_shrink_state, false);
      textSize = array.getDimensionPixelSize(R.styleable.ShrinkUpvoteView_shrink_prompt_size, 10);
      promptStr =array.getString(R.styleable.ShrinkUpvoteView_shrink_prompt_text);
      array.recycle();
    } else {
      initDefault();
    }
    if(width*2>=height){
      height=width*5/2;
    }

    initUnselectColor();
    paint = new Paint();
    paint.setAntiAlias(true);
    paint.setStrokeCap(Paint.Cap.ROUND);//设置线帽样式，为圆形

    textPaint = new TextPaint();
    textPaint.setColor(Color.BLACK);
    textPaint.setAntiAlias(true);
    textPaint.setTypeface(Typeface.DEFAULT_BOLD);

    setCurColor(defaultState);
    initParams();
    initSelfParams();
    initPromptSizeParams();
  }

  /**
   * 初始化当前表情所需的一些元素
   */
  protected abstract void initSelfParams();

  /**
   * 设置当前的颜色
   */
  private void setCurColor(boolean defaultState) {
    this.defaultState = defaultState;
    if (defaultState) {
      colorBorder = colorBorderSel;
      colorFill = colorFillSel;
    } else {
      colorBorder = colorBorderUnsel;
      colorFill = colorFillUnsel;
    }
  }

  /**
   * 默认的初始值
   */
  protected void initDefault() {
    colorBorder = Color.RED;
    colorFill = Color.YELLOW;
    width = 25;
    height = 100;
    selectState = true;
    promptStr ="null";
  }

  /**
   * 初始化一些参数
   */
  protected void initParams() {
    radius = positionX = width / 2;
    positionY = height - radius;

    eyeRadius = width / 10;
    eyeToMiddleX = width / 6;
    eyeToTopY = eyeRadius;
    borderWidth = eyeRadius / 2;
  }

  /**
   * 初始化未选中时的颜色
   */
  private void initUnselectColor() {
    colorBorderUnsel = getContext().getResources().getColor(R.color.deep_grey);
    colorFillUnsel = getContext().getResources().getColor(R.color.grey);
  }

  /**
   * 重新设置当前表情的尺寸
   */
  @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    setMeasuredDimension((int) width, (int) height);
  }

  @Override protected void onDraw(Canvas canvas) {

    paint.setColor(colorBorder);
    RectF rBottom =
        new RectF(positionX - radius, positionY - 2 * radius, positionX + radius, positionY);
    canvas.drawArc(rBottom, 0, 180, true, paint);

    paint.setColor(colorFill);
    RectF rBottomInner = new RectF(rBottom.left + borderWidth, rBottom.top + borderWidth,
        rBottom.right - borderWidth, rBottom.bottom - borderWidth);
    canvas.drawArc(rBottomInner, 0, 180, true, paint);

    paint.setColor(colorBorder);
    RectF rMiddle =
        new RectF(positionX - radius, positionY - radius - curOffsetY, positionX + radius,
            positionY - radius);
    canvas.drawRect(rMiddle, paint);

    paint.setColor(colorFill);
    RectF rMiddleInner =
        new RectF(rMiddle.left + borderWidth, rMiddle.top, rMiddle.right - borderWidth,
            rMiddle.bottom);
    canvas.drawRect(rMiddleInner, paint);

    paint.setColor(colorBorder);
    RectF rTop =
        new RectF(positionX - radius, positionY - 2 * radius - curOffsetY, positionX + radius,
            positionY - curOffsetY);
    canvas.drawArc(rTop, 180, 180, true, paint);

    paint.setColor(colorFill);
    RectF rTopInner =
        new RectF(rTop.left + borderWidth, rTop.top + borderWidth, rTop.right - borderWidth,
            rTop.bottom - borderWidth);
    canvas.drawArc(rTopInner, 180, 180, true, paint);

    if (curOffsetY > 0) {
      canvas.drawText(promptStr, startPromX, rTop.top - startPromY, textPaint);
    }

    drawFace(canvas, curOffsetY);
  }

  /**
   * 初始化绘制提示信息的参数
   */
  private void initPromptSizeParams() {
    //Log.i(TAG, "initPromptSizeParams: "+textSize);
    //float density =getContext().getResources().getDisplayMetrics().scaledDensity;//缩放尺寸 2
    textPaint.setTextSize(textSize);
    float textWidth = textPaint.measureText(promptStr);
    float desc = textPaint.descent();
    startPromX = positionX - textWidth / 2;
    startPromY = desc;
  }

  /**
   * 绘制表情
   */
  protected abstract void drawFace(Canvas canvas, float offsetY);

  /**
   * 表情抖动控制流程
   * 该方法运行在子线程中
   */
  protected abstract void shrinkControl();

  @Override public void onClick(View v) {
    if (selectState) {
      return;
    }
    selectState = true;
    setCurColor(selectState);
    if (listener != null) {
      listener.notifyOthers(this, true);
    }
    startGrown();
  }

  /**
   * 表情生长控制流程
   */
  private void startGrown() {
    ThreadManager.getShortPool().execute(() -> {
      float canGrownHeight = radius;
      while (curOffsetY < canGrownHeight) {
        curOffsetY += INCRES_DELY;
        if (curOffsetY >= canGrownHeight) {
          curOffsetY = canGrownHeight;
        }
        try {
          Thread.sleep(SHRINK_TIME);
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
        postInvalidate();
      }
      shrinkControl();
      while (curOffsetY > 0) {
        curOffsetY -= INCRES_DELY;
        if (curOffsetY <= 0) {
          curOffsetY = 0;
        }
        try {
          Thread.sleep(SHRINK_TIME);
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
        postInvalidate();
      }
      selectState = false;
      post(() -> {
        if (listener != null) {
          listener.notifyOthers(ShrinkUpvoteView.this, false);
        }
      });
    });
  }

  /**
   * 改变状态，并通知其他表情
   */
  public void setSelectState(boolean state) {
    selectState = state;
    if (selectState) {
      setCurColor(!state);
    } else {
      setCurColor(state);
    }
    invalidate();
  }

  private ShrinkLinkageListener listener;

  public void setListener(ShrinkLinkageListener listener) {
    this.listener = listener;
  }

}
